using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories;
using Matrix.Notification.Domain.Shared.Notifications;

namespace Matrix.Notification.Domain.Notifications
{
    /// <summary>
    /// 通知订阅仓储接口
    /// </summary>
    public interface INotificationSubscriptionRepository : IRepository<NotificationSubscription, Guid>
    {
        /// <summary>
        /// 根据用户ID获取订阅
        /// </summary>
        Task<NotificationSubscription?> GetByUserIdAsync(
            Guid userId,
            Guid? tenantId = null,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 根据邮箱获取订阅
        /// </summary>
        Task<List<NotificationSubscription>> GetByEmailAsync(
            string email,
            Guid? tenantId = null,
            bool? isEnabled = null,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 根据手机号获取订阅
        /// </summary>
        Task<List<NotificationSubscription>> GetByPhoneNumberAsync(
            string phoneNumber,
            Guid? tenantId = null,
            bool? isEnabled = null,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 根据用户名获取订阅
        /// </summary>
        Task<NotificationSubscription?> GetByUserNameAsync(
            string userName,
            Guid? tenantId = null,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 获取启用的订阅列表
        /// </summary>
        Task<List<NotificationSubscription>> GetEnabledSubscriptionsAsync(
            Guid? tenantId = null,
            int maxResultCount = 10,
            int skipCount = 0,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 获取全局禁用的订阅列表
        /// </summary>
        Task<List<NotificationSubscription>> GetGloballyDisabledSubscriptionsAsync(
            Guid? tenantId = null,
            int maxResultCount = 10,
            int skipCount = 0,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 获取订阅指定类型的用户
        /// </summary>
        Task<List<NotificationSubscription>> GetSubscribedToTypeAsync(
            NotificationType type,
            Guid? tenantId = null,
            bool? isEnabled = null,
            int maxResultCount = 10,
            int skipCount = 0,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 获取启用指定渠道的用户
        /// </summary>
        Task<List<NotificationSubscription>> GetWithEnabledChannelAsync(
            NotificationChannel channel,
            Guid? tenantId = null,
            bool? isEnabled = null,
            int maxResultCount = 10,
            int skipCount = 0,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 根据分类获取订阅
        /// </summary>
        Task<List<NotificationSubscription>> GetBySubscribedCategoryAsync(
            string category,
            Guid? tenantId = null,
            bool? isEnabled = null,
            int maxResultCount = 10,
            int skipCount = 0,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 获取允许营销通知的用户
        /// </summary>
        Task<List<NotificationSubscription>> GetMarketingAllowedSubscriptionsAsync(
            Guid? tenantId = null,
            bool? isEnabled = null,
            int maxResultCount = 10,
            int skipCount = 0,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 获取允许系统通知的用户
        /// </summary>
        Task<List<NotificationSubscription>> GetSystemNotificationAllowedSubscriptionsAsync(
            Guid? tenantId = null,
            bool? isEnabled = null,
            int maxResultCount = 10,
            int skipCount = 0,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 获取允许安全通知的用户
        /// </summary>
        Task<List<NotificationSubscription>> GetSecurityNotificationAllowedSubscriptionsAsync(
            Guid? tenantId = null,
            bool? isEnabled = null,
            int maxResultCount = 10,
            int skipCount = 0,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 根据语言偏好获取订阅
        /// </summary>
        Task<List<NotificationSubscription>> GetByLanguagePreferenceAsync(
            string language,
            Guid? tenantId = null,
            bool? isEnabled = null,
            int maxResultCount = 10,
            int skipCount = 0,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 根据时区偏好获取订阅
        /// </summary>
        Task<List<NotificationSubscription>> GetByTimeZonePreferenceAsync(
            string timeZone,
            Guid? tenantId = null,
            bool? isEnabled = null,
            int maxResultCount = 10,
            int skipCount = 0,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 根据标签获取订阅
        /// </summary>
        Task<List<NotificationSubscription>> GetByTagsAsync(
            string[] tags,
            Guid? tenantId = null,
            bool? isEnabled = null,
            int maxResultCount = 10,
            int skipCount = 0,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 获取活跃订阅（最近活跃的用户）
        /// </summary>
        Task<List<NotificationSubscription>> GetActiveSubscriptionsAsync(
            DateTime? since = null,
            Guid? tenantId = null,
            int maxResultCount = 10,
            int skipCount = 0,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 获取不活跃订阅（长期未活跃的用户）
        /// </summary>
        Task<List<NotificationSubscription>> GetInactiveSubscriptionsAsync(
            DateTime? before = null,
            Guid? tenantId = null,
            int maxResultCount = 10,
            int skipCount = 0,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 检查用户是否订阅指定类型
        /// </summary>
        Task<bool> IsSubscribedToTypeAsync(
            Guid userId,
            NotificationType type,
            Guid? tenantId = null,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 检查用户是否启用指定渠道
        /// </summary>
        Task<bool> IsChannelEnabledAsync(
            Guid userId,
            NotificationChannel channel,
            Guid? tenantId = null,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 检查用户是否可以接收通知
        /// </summary>
        Task<bool> CanReceiveNotificationAsync(
            Guid userId,
            NotificationType type,
            NotificationChannel channel,
            Guid? tenantId = null,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 获取可以接收指定通知的用户列表
        /// </summary>
        Task<List<NotificationSubscription>> GetEligibleRecipientsAsync(
            NotificationType type,
            NotificationChannel channel,
            string? category = null,
            Guid? tenantId = null,
            int maxResultCount = 100,
            int skipCount = 0,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 批量检查用户订阅状态
        /// </summary>
        Task<Dictionary<Guid, bool>> BatchCheckSubscriptionAsync(
            List<Guid> userIds,
            NotificationType type,
            NotificationChannel channel,
            Guid? tenantId = null,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 重置每日统计数据
        /// </summary>
        Task<int> ResetDailyStatisticsAsync(
            DateTime? resetDate = null,
            Guid? tenantId = null,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 获取订阅统计信息
        /// </summary>
        Task<SubscriptionStatistics> GetStatisticsAsync(
            Guid? tenantId = null,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 获取用户的通知偏好统计
        /// </summary>
        Task<UserNotificationPreferences> GetUserPreferencesAsync(
            Guid userId,
            Guid? tenantId = null,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 更新最后活跃时间
        /// </summary>
        Task<int> UpdateLastActiveTimeAsync(
            List<Guid> userIds,
            DateTime activeTime,
            Guid? tenantId = null,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 更新最后接收通知时间
        /// </summary>
        Task<int> UpdateLastNotificationTimeAsync(
            List<Guid> userIds,
            DateTime notificationTime,
            Guid? tenantId = null,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 批量全局禁用
        /// </summary>
        Task<int> BatchGlobalDisableAsync(
            List<Guid> userIds,
            string reason,
            DateTime? expiryTime = null,
            Guid? tenantId = null,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 批量取消全局禁用
        /// </summary>
        Task<int> BatchCancelGlobalDisableAsync(
            List<Guid> userIds,
            Guid? tenantId = null,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 获取过期全局禁用的订阅
        /// </summary>
        Task<List<NotificationSubscription>> GetExpiredGlobalDisablesAsync(
            DateTime? beforeTime = null,
            Guid? tenantId = null,
            int maxResultCount = 10,
            int skipCount = 0,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 清理不活跃的订阅
        /// </summary>
        Task<int> CleanupInactiveSubscriptionsAsync(
            DateTime? inactiveSince = null,
            Guid? tenantId = null,
            int maxResultCount = 1000,
            CancellationToken cancellationToken = default);
    }

    /// <summary>
    /// 订阅统计信息
    /// </summary>
    public class SubscriptionStatistics
    {
        /// <summary>
        /// 总订阅数
        /// </summary>
        public int TotalCount { get; set; }

        /// <summary>
        /// 启用订阅数
        /// </summary>
        public int EnabledCount { get; set; }

        /// <summary>
        /// 禁用订阅数
        /// </summary>
        public int DisabledCount { get; set; }

        /// <summary>
        /// 全局禁用订阅数
        /// </summary>
        public int GloballyDisabledCount { get; set; }

        /// <summary>
        /// 按通知类型统计
        /// </summary>
        public Dictionary<NotificationType, int> CountByNotificationType { get; set; } = new();

        /// <summary>
        /// 按渠道统计
        /// </summary>
        public Dictionary<NotificationChannel, int> CountByChannel { get; set; } = new();

        /// <summary>
        /// 允许营销通知的用户数
        /// </summary>
        public int MarketingAllowedCount { get; set; }

        /// <summary>
        /// 允许系统通知的用户数
        /// </summary>
        public int SystemNotificationAllowedCount { get; set; }

        /// <summary>
        /// 允许安全通知的用户数
        /// </summary>
        public int SecurityNotificationAllowedCount { get; set; }

        /// <summary>
        /// 按语言偏好统计
        /// </summary>
        public Dictionary<string, int> CountByLanguage { get; set; } = new();

        /// <summary>
        /// 按时区偏好统计
        /// </summary>
        public Dictionary<string, int> CountByTimeZone { get; set; } = new();

        /// <summary>
        /// 活跃用户数（最近30天）
        /// </summary>
        public int ActiveUsersCount { get; set; }

        /// <summary>
        /// 不活跃用户数（超过30天未活跃）
        /// </summary>
        public int InactiveUsersCount { get; set; }

        /// <summary>
        /// 平均每日接收限制
        /// </summary>
        public double AverageDailyLimit { get; set; }
    }

    /// <summary>
    /// 用户通知偏好
    /// </summary>
    public class UserNotificationPreferences
    {
        /// <summary>
        /// 用户ID
        /// </summary>
        public Guid UserId { get; set; }

        /// <summary>
        /// 用户名
        /// </summary>
        public string UserName { get; set; } = string.Empty;

        /// <summary>
        /// 邮箱地址
        /// </summary>
        public string? EmailAddress { get; set; }

        /// <summary>
        /// 手机号码
        /// </summary>
        public string? PhoneNumber { get; set; }

        /// <summary>
        /// 是否启用
        /// </summary>
        public bool IsEnabled { get; set; }

        /// <summary>
        /// 是否全局禁用
        /// </summary>
        public bool IsGloballyDisabled { get; set; }

        /// <summary>
        /// 订阅的通知类型
        /// </summary>
        public List<NotificationType> SubscribedTypes { get; set; } = new();

        /// <summary>
        /// 启用的通知渠道
        /// </summary>
        public List<NotificationChannel> EnabledChannels { get; set; } = new();

        /// <summary>
        /// 禁用的通知渠道
        /// </summary>
        public List<NotificationChannel> DisabledChannels { get; set; } = new();

        /// <summary>
        /// 订阅的分类
        /// </summary>
        public List<string> SubscribedCategories { get; set; } = new();

        /// <summary>
        /// 是否允许营销通知
        /// </summary>
        public bool AllowMarketingNotifications { get; set; }

        /// <summary>
        /// 是否允许系统通知
        /// </summary>
        public bool AllowSystemNotifications { get; set; }

        /// <summary>
        /// 是否允许安全通知
        /// </summary>
        public bool AllowSecurityNotifications { get; set; }

        /// <summary>
        /// 默认优先级
        /// </summary>
        public NotificationPriority DefaultPriority { get; set; }

        /// <summary>
        /// 每日最大接收数量
        /// </summary>
        public int DailyMaxCount { get; set; }

        /// <summary>
        /// 今日已接收数量
        /// </summary>
        public int TodayReceivedCount { get; set; }

        /// <summary>
        /// 语言偏好
        /// </summary>
        public string LanguagePreference { get; set; } = "zh-CN";

        /// <summary>
        /// 时区偏好
        /// </summary>
        public string TimeZonePreference { get; set; } = "Asia/Shanghai";

        /// <summary>
        /// 最后活跃时间
        /// </summary>
        public DateTime? LastActiveTime { get; set; }

        /// <summary>
        /// 最后接收通知时间
        /// </summary>
        public DateTime? LastNotificationTime { get; set; }

        /// <summary>
        /// 订阅标签
        /// </summary>
        public List<string> Tags { get; set; } = new();
    }
}